/*
 * $Log: KickableLayer.java,v $ Revision 1.4 2006/11/05 13:57:59 wetzker more
 * merging - CLang + MF + some states still missing
 * 
 * Revision 1.3.26.1 2006/07/26 15:28:26 endert Formatted Code
 * 
 * Revision 1.3 2006/03/26 17:36:51 wetzker hope to finally got the tackle area
 * displayed right
 * 
 * Revision 1.2 2006/03/22 23:34:56 wetzker tackle area is now shown in
 * soccerscope by default tackle area contains now the backward area as well
 * 
 * Revision 1.1 2006/03/13 07:37:39 axle moved from ROOT/src for Maven 2
 * Buildsystem and Team/Soccerscope separation
 * 
 * Revision 1.4 2006/03/07 12:46:20 endert Merge after refactoring: - New
 * State-Interface: One Method for each action type - Action Bean removed -
 * ActionFactorys for helper methods, States calculate main-Action themselves -
 * formatted code - added State-List in Monitor (Context-Menu of Player) - other
 * smaller stuff
 * 
 * Revision 1.3.2.1 2006/02/25 22:07:05 wetzker formated
 * 
 * Revision 1.3 2006/02/22 16:05:01 endert This is done: - Rebound SoccerScope
 * to Agents (can be added or removed in config-file) - Situations now all
 * extend abstract class Situation - Refactorings: ActionBean _ removed from
 * Attributes - SoccerScope will automatically connect to host given in
 * Start-Call - Trainer uses the same host as soccerscope - Removed unused stuff
 * (old confs, bat, etc.) - Code formatted (good luck when merging) - organized
 * imports - all that i forgot to mention here
 * 
 * Revision 1.2 2005/10/25 20:51:36 endert Added Training-Editor to SoccerScope,
 * restructuring in some old classes and some experimental stuff (goals,
 * commitments, mental model)
 * 
 * Revision 1.1.14.1 2005/10/10 11:05:08 endert New Training-Scenario Editor!
 * There exists a dialog, which opens on middle-mouse click on the field. From
 * here, the Trainings-Scenario may be specified in a more comfortable manner.
 * The Trainings-Scenario is also visualized on the Field - using the
 * TrainingModelLayer. The TrainingModel itself contains all data specified in
 * the scenario, and therefor can be serialized to HDD, using an XML-Stream
 * generator (XStream). The Scenario editor is still under development.
 * 
 * Revision 1.1 2005/04/20 10:38:39 endert Fresh Team Repository installation
 * from /home/e/endert/Robocup to here.
 * 
 * Revision 1.3 2005/02/06 07:20:10 maketi Added soccerscope with connection to
 * our world model
 * 
 * Revision 1.11 2002/12/10 03:59:08 koji
 * ���å����ϰϤ򥪥ץ������r褹�뤳�Ȥ�
 * 
 * Revision 1.10 2002/10/17 09:34:19 koji canTackle����Ѥ���褦�˽�5
 * 
 * Revision 1.9 2002/10/10 09:43:40 koji ͥ*�ΰ�η׻��β���
 * (Direction-Distance Table)
 * 
 * Revision 1.8 2002/10/04 10:39:23 koji
 * Tuple,Point,Vector�Υѥå������ѹ���Geometry,Circle,Line,Rectangle�ɲ�
 * 
 * Revision 1.7 2002/09/12 17:07:08 koji HeteroParam�d�ä��ѹ���Hetro->Hetero
 * 
 * Revision 1.6 2002/09/12 15:28:31 koji
 * ������%����?���ɲ�,ColorTool��Color2�����
 * 
 * Revision 1.5 2002/09/05 10:21:25 taku-ako �إƥ�ץ쥤�䡼���б�
 * 
 * Revision 1.4 2002/09/02 07:06:28 taku-ako Geometry��Ϣ�Υ饤�֥����.
 * 
 * Revision 1.3 2002/06/06 09:49:00 koji ���å����.��Ψ�η׻���5
 * 
 * Revision 1.2 2002/06/04 05:58:18 koji Tackle�θ�̤�ɽ��
 * 
 * Revision 1.1.1.1 2002/03/01 14:12:52 koji CVS�����
 * 
 */

package soccerscope.view.layer;

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;

import javax.swing.AbstractButton;
import javax.swing.JCheckBox;
import javax.swing.JPanel;

import soccerscope.model.ClientScene;
import soccerscope.model.Param;
import soccerscope.util.geom.Point2f;
import soccerscope.util.geom.Tuple2f;
import soccerscope.util.geom.Vector2f;
import soccerscope.view.FieldPane;

public class KickableLayer
    extends Layer {

  public KickableLayer(
      FieldPane fieldPane,
      boolean enable) {

    super(fieldPane, enable);
  }

  @Override
  public String getLayerName() {

    return "Kickable";
  }

  private boolean   dtackle = true;

  private JCheckBox tackleCB;

  @Override
  public JPanel getConfigPanel() {

    JPanel panel = new JPanel();

    this.tackleCB = new JCheckBox("Tackle Area");
    this.tackleCB.addActionListener(new KickableLayerActionListener());
    panel.add(this.tackleCB);

    return panel;
  }

  class KickableLayerActionListener
      implements ActionListener {

    public void actionPerformed(ActionEvent ie) {

      Object o = ie.getSource();
      boolean b = ((AbstractButton) o).isSelected();
      if (o == KickableLayer.this.tackleCB) {
        KickableLayer.this.dtackle = b;
      }
    }
  }

  private Vector2f diff    = new Vector2f();

  private Point2f  nextPos = new Point2f();
  private Point2f  topLeft = new Point2f();
  private Tuple2f  arcSize = new Tuple2f();
  private Color lightTrans= new Color(255,255,255,50);
  private Color darkTrans= new Color(0,0,0,50);

  @Override
  public void draw(Graphics g) {

    if (!this.enable) {
      return;
    }

    ClientScene clientScene = this.fieldPane.getScene();
    float ballMagnify = this.fieldPane.getBallMagnify();
    float playerMagnify = this.fieldPane.getPlayerMagnify();
    for (int i = 0; i < Param.MAX_PLAYER * 2; i++) {
      if (!clientScene.player[i].isEnable()) {
        continue;
      }

      float playerR = clientScene.player[i].getSize() * playerMagnify;
      Color drawColor = clientScene.player[i].getColor();

      // draw kickable and catchable area
      float drawR;
      drawR = clientScene.player[i].getKickable();//Param.KICKABLE_R;
      if (clientScene.player[i].isKicking()) {
        if (clientScene.player[i].isKickFault()) {
          g.setColor(drawColor.darker().darker());
        }
        else {
          g.setColor(drawColor.darker());
        }
        Graphics2D g2 = (Graphics2D) g;
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
            0.3f));
        this.fillCircle(g, clientScene.player[i].pos, drawR);
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
            1.0f));
      }
      g.setColor(drawColor);
      this.drawCircle(g, clientScene.player[i].pos, drawR);

      if (clientScene.player[i].isGoalie()) {
        drawR = Param.GOALIE_CATCHABLE_AREA_LENGTH;
        if (clientScene.player[i].isCatching()) {
          if (clientScene.player[i].isCatchFault()) {
            g.setColor(drawColor.darker().darker());
          }
          else {
            g.setColor(drawColor.darker());
          }
          this.fillCircle(g, clientScene.player[i].pos, drawR);
        }
        g.setColor(drawColor);
        this.drawCircle(g, clientScene.player[i].pos, drawR);
      }

      if (clientScene.player[i].isTackling()) {
        if (clientScene.player[i].isTackleFault()) {
          g.setColor(drawColor.darker().darker());
        }
        else {
          g.setColor(drawColor.darker());
        }
        if (this.dtackle) {
          this.fillRect(g, new Point2f(
              clientScene.player[i].pos.x - Param.TACKLE_BACK_DIST,
              clientScene.player[i].pos.y - Param.TACKLE_WIDTH / 2.0f),
              new Point2f(Param.TACKLE_DIST + Param.TACKLE_BACK_DIST,
                  Param.TACKLE_WIDTH), (int) clientScene.player[i].angle,
              clientScene.player[i].pos);
        }
      }

      g.setColor(drawColor);
      if (this.dtackle) {
        this.drawRect(g, new Point2f(
            clientScene.player[i].pos.x - Param.TACKLE_BACK_DIST,
            clientScene.player[i].pos.y - Param.TACKLE_WIDTH / 2.0f),
            new Point2f(Param.TACKLE_DIST + Param.TACKLE_BACK_DIST,
                Param.TACKLE_WIDTH), (int) clientScene.player[i].angle,
            clientScene.player[i].pos);
      }

      if (clientScene.player[i].isKickable(clientScene.ball.pos)) {
        Vector2f acc = clientScene.player[i].getKickAccelerate(
            clientScene.ball.pos, 100.0f, 0.0f);
        float kickableRange = acc.length();
        this.nextPos.add(clientScene.ball.pos, clientScene.ball.vel);
        this.topLeft.x= clientScene.ball.pos.x-Param.BALL_SPEED_MAX;
        this.topLeft.y= clientScene.ball.pos.y-Param.BALL_SPEED_MAX;
        this.arcSize.x= Param.BALL_SPEED_MAX*2;
        this.arcSize.y= Param.BALL_SPEED_MAX*2;
        g.setColor(lightTrans);
        this.fillArc(g, topLeft, arcSize, 0, 360);
        g.setColor(drawColor);
        this.drawArc(g, topLeft, arcSize, 0, 360);
        this.topLeft.x= nextPos.x-kickableRange;
        this.topLeft.y= nextPos.y-kickableRange;
        this.arcSize.x= kickableRange*2;
        this.arcSize.y= kickableRange*2;
        g.setColor(darkTrans);
        this.fillArc(g, topLeft, arcSize, 0, 360);
        g.setColor(drawColor);
        this.drawArc(g, topLeft, arcSize, 0, 360);
      }

      if (this.dtackle && clientScene.player[i].canTackle(clientScene.ball.pos)) {
        float prob = clientScene.player[i].getTackleProb(clientScene.ball.pos);
        Point2f drawPoint = new Point2f();
        Point2f drawOffset = new Point2f(0.0f, playerR * 2.0f);
        drawPoint.add(clientScene.player[i].pos, drawOffset);
        this.drawString(g, String.valueOf(prob), drawPoint);
      }
    }
  }
}
